package com.ymwk;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.ymwk.base64.Base64Utils;
import com.ymwk.result.Result;
import com.ymwk.sm2.GMBaseUtil;
import com.ymwk.sm2.SM2CertUtil;
import com.ymwk.sm2.SM2Util;
import com.ymwk.sm4.Sm4Utils;

/**
 * 对文件的数字信封
 * @author Saxon 
 * @Date   2021年7月8日
 */
public class FileEncrypt extends GMBaseUtil{
	
	
	
	/**
	 * 
	 * @param publicKey 公钥对象
	 * @param orgIn   原文件输入流
	 * @param encryptPath  加密后保存地址
	 * @return Result if(code== 200）success else fail   
	 * encryptKeyStr 加密后的秘钥字符串
	 */
	public static Result fileEncrypt(PublicKey publicKey,InputStream orgIn,String encryptPath)  {
		try {
			//创建对称秘钥对
			byte[] key = Sm4Utils.generateKey();	
			System.out.println("sm4的对称秘钥为: "+Base64Utils.encode(key));
			//对文件加密
			boolean flag = Sm4Utils.encrypt_ECB_Padding(key, orgIn,encryptPath);			
			if(!flag) {
				File file = new File(encryptPath);
				if(file.exists()) file.delete(); 
				return new Result(Result.CODE_ERROR,"文件加密失败!");
			}
			//对秘钥对加密
			byte[] encryptKey = SM2Util.encrypt((BCECPublicKey)publicKey, key);
			//将返回值base64加密
			String encryptKeyStr = Base64Utils.encode(encryptKey);
			return new Result(Result.CODE_SUCCESS,"文件加密成功",encryptKeyStr);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return new Result(Result.CODE_EXCEPTION, "NoSuchAlgorithmException,没有找到该摘要算法");
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
			return new Result(Result.CODE_EXCEPTION, "NoSuchProviderException,没有找到该加密机");
		}catch (Exception e ) {
			e.printStackTrace();
			return new Result(Result.CODE_EXCEPTION, "文件加密失败:"+e.getMessage());
		}
	}

	

	
	/**
	 * 
	 * @param cert 证书对象
	 * @param orgIn   原文件输入流
	 * @param encryptPath  加密后保存地址
	 * @return Result if(code== 200）success else fail   
	 * encryptKeyStr 加密后的秘钥字符串
	 */
	public static Result fileEncrypt(X509Certificate cert,InputStream orgIn,String encryptPath)  {
		return fileEncrypt(SM2CertUtil.getBCECPublicKey(cert),orgIn,encryptPath);
	}
	
	
	/**
	 * 
	 * @param certStr 证书base64
	 * @param orgIn   原文件输入流
	 * @param encryptPath  加密后保存地址
	 * @return Result if(code== 200）success else fail   
	 * encryptKeyStr 加密后的秘钥字符串
	 */
	public static Result fileEncrypt(String certStr,InputStream orgIn,String encryptPath) {
		try {
		   ByteArrayInputStream bais = new ByteArrayInputStream(Base64Utils.decode(certStr));
		   CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
		   X509Certificate cert =  (X509Certificate) cf.generateCertificate(bais);
		   return fileEncrypt(cert,orgIn,encryptPath);
		}catch (Exception e) {
			e.printStackTrace();
			return new Result(Result.CODE_EXCEPTION, "证书base64转换证书对象失败:"+e.getMessage());
		}
	}
	
	
	
}
